package com.sywl.ytcx.service.Impl;


import com.sywl.ytcx.config.PostStatsVO;
import com.sywl.ytcx.config.UserContentVO;
import com.sywl.ytcx.entity.atwork.Atwork;
import com.sywl.ytcx.entity.post.Post;
import com.sywl.ytcx.entity.res.ResponseResult;
import com.sywl.ytcx.entity.user.User;
import com.sywl.ytcx.entity.user.UserLikeTag;
import com.sywl.ytcx.mapper.ArtworkMapper;
import com.sywl.ytcx.mapper.PostMapper;
import com.sywl.ytcx.mapper.PostTagMapper;
import com.sywl.ytcx.mapper.UserMapper;
import com.sywl.ytcx.service.UserService;
import com.sywl.ytcx.util.JwtUtil;
import com.sywl.ytcx.util.VerTokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    UserMapper userMapper;

    @Autowired
    private ThreadPoolExecutor userContentExecutor;

    @Autowired
    private PostTagMapper postTagMapper;

    @Autowired
    private PostMapper postMapper;

    @Autowired
    private ArtworkMapper artworkMapper;

    // 定义常量
    private static final String ACCESS_TOKEN_KEY = "access_token";

    /**
     * 注册用户
     * @param user
     * @return 注册结果信息
     * */
    @Override
    public ResponseResult registerUser(User user) {
        // 检查用户是否已存在
        System.out.println(user);
        if (userMapper.selectUserByAccount(user.getAccount()) != null) {
            return new ResponseResult("E002", "用户名已存在", null);
        }


        // 密码加密
        user.setPassword_hash(user.getPassword_hash());

        // 设置默认值
        user.setCreated_at(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date()));
        user.setUpdated_at(user.getCreated_at());
        user.setStatus("active");

        // 保存用户
        int rows = userMapper.insertUser(user);


        if (rows > 0) {
            return loginUser(user.getAccount(), user.getPassword_hash());
//            return new ResponseResult("S200", "注册成功", null);
        } else {
            return new ResponseResult("E403", "注册失败，请稍后重试", null);
        }
    }

    /**
     * 登录用户
     *
     * @param account  用户名
     * @param password 密码
     * @return 登录结果信息
     **/
    @Override
    public ResponseResult loginUser(String account, String password) {
        System.out.println("登录用户：" + account);

        User user = userMapper.loginUser(account, password);
        if (account == null || password == null) return new ResponseResult("E001", "缺少必要参数", null);
        if (user == null) return new ResponseResult("E003", "用户不存在或密码错误", null);
        // 登录成功，生成token,已经写好，可参考JwtUtil类
        Map<String, Object> tokenMap = new HashMap<>();

        Map<String, String> payload = new HashMap<>();
        payload.put("user_id", String.valueOf(user.getUser_id()));
        payload.put("username", user.getUsername());
        String token = JwtUtil.getToken(payload, 604800);
        try {
            tokenMap.put("state", true);
            tokenMap.put("msg", "认证成功");
            tokenMap.put(ACCESS_TOKEN_KEY, token);// 响应token    *
        } catch (Exception e) {
            tokenMap.put("state", false);
            tokenMap.put("msg", "认证失败");
            tokenMap.put(ACCESS_TOKEN_KEY, null);// 响应token    *
        }
        return new ResponseResult(200, "登录成功", tokenMap);


    }

    @Override
    public ResponseResult updateUserStatus(String token, String status) {
        int userId = VerTokenUtil.getUserId(token);

        if (userId == -1) {
            return new ResponseResult("E001", "数据为空", null);
        }
        int result = userMapper.updateUserStatus(userId,status);
        return new ResponseResult("S200", "修改成功", status);
    }

    @Override
    public ResponseResult getUserById(String token) {
        int userId = VerTokenUtil.getUserId(token);
        if (userId == -1) {
            return new ResponseResult("E005", "数据为空", null);
        }
        User user = userMapper.selectUserById(userId);
        return new ResponseResult("E005", "查询成功", user);
    }

    @Override
    public ResponseResult updateAvatarUrl(String token, MultipartFile file) {
        return null;
    }


    /**
     * 异步用户创作数据
     * 包括用户作品列表、作品数量统计和帖子统计数据
     * 使用并行处理提高查询效率
     *
     * @param userId 用户ID
     * @return CompletableFuture<ResponseResult> 包含用户内容数据的响应结果
     */
    @Override
    public CompletableFuture<ResponseResult> getUserContent(int userId) {
        // 参数校验：检查用户ID是否有效
        if (userId <= 0) {
            // 如果用户ID无效，返回已完成的CompletableFuture，包含错误信息
            return CompletableFuture.completedFuture(
                    new ResponseResult("U100", "userId 不能小于等于0", null)
            );
        }

        // 并行发起三次查询，提高查询效率
        // 查询用户的作品列表数据
        CompletableFuture<List<Atwork>> fArts = CompletableFuture.supplyAsync(
                () -> artworkMapper.selectArtworksByUser(userId),
                userContentExecutor
        );

        // 查询用户的作品总数
        CompletableFuture<Integer> fCount = CompletableFuture.supplyAsync(
                () -> artworkMapper.countArtworksByUser(userId),
                userContentExecutor
        );

        // 查询用户的帖子统计信息
        CompletableFuture<PostStatsVO> fStats = CompletableFuture.supplyAsync(
                () -> postMapper.selectPostStatsByUser(userId),
                userContentExecutor
        );

        CompletableFuture<List<Post>> fPost = CompletableFuture.supplyAsync(
                () -> postMapper.selectPostsByUser(userId),
                userContentExecutor
        );


        // 等待所有并行查询完成后再进行数据聚合
        return CompletableFuture.allOf(fArts, fCount, fStats)
                // 设置全局超时：最多等待 5 秒，防止长时间阻塞
                .orTimeout(5, TimeUnit.SECONDS)
                .thenApply(v -> {
                    // 所有查询都成功完成，进行数据聚合
                    UserContentVO vo = new UserContentVO();
                    // 设置用户作品列表
                    vo.setArtworks(fArts.join());
                    // 设置用户作品总数
                    vo.setArtworkCount(fCount.join());
                    // 设置用户帖子统计信息
                    vo.setPostStats(fStats.join());
                    // 设置用户帖子列表
                    vo.setPost(fPost.join());

                    // 返回成功响应结果
                    return new ResponseResult("200", "查询用户创作数据报表成功", vo);
                })
                .exceptionally(ex -> {
                    // 异常处理：如果任一子任务超时或抛出异常，执行此逻辑
                    // 记录错误信息并返回失败响应
                    return new ResponseResult(
                            "U400",
                            "查询用户创作数据报表部分数据加载失败：" + ex.getMessage(),
                            null
                    );
                });
    }


    /*
    添加用户喜好标签
     */
    @Override
    public ResponseResult addUserLikeTag(Integer userId, Integer postId) {
        // 根据postId获取标签ID
        Integer tagId = postTagMapper.getTagIdByPostId(postId);
        if (tagId == null) {
            return new ResponseResult("ULT400", "未找到对应帖子标签", null);
        }
        int rows = userMapper.insert(userId, tagId);
        if (rows > 0) {
            return new ResponseResult(200, "添加喜好标签成功", null);
        } else {
            return new ResponseResult("ULT400", "添加喜好标签失败", null);
        }
    }

    /**
     * 获取所有用户喜好标签
     * @return ResponseResult 包含所有用户喜好标签的响应结果
     */
    @Override
    public ResponseResult getAllUserLikeTags() {
        try {
            List<UserLikeTag> list = userMapper.selectAll();
            return new ResponseResult("ULT400", "查询所有喜好标签成功", list);
        } catch (Exception e) {
            log.error("查询所有用户喜好标签异常", e);
            return new ResponseResult("ULT400", "查询所有喜好标签时发生异常", null);
        }
    }

    /**
     * 根据用户ID获取用户喜好标签
     * @return ResponseResult
     */
    @Override
    public ResponseResult getUserLikeTagsByUserId(Integer userId) {
        try {
            List<UserLikeTag> list = userMapper.selectByUserId(userId);
            return new ResponseResult("ULT400", "根据用户ID查询喜好标签成功", list);
        } catch (Exception e) {
            log.error("根据用户ID查询用户喜好标签异常", e);
            return new ResponseResult("ULT400", "根据用户ID查询喜好标签时发生异常", null);
        }
    }


}